﻿using System.Threading;

namespace Quail.Helpers
{
    /// <summary>
    /// Some somewhat helpful extension methods into the Thread object
    /// </summary>
    public static class Threads
    {
        /// <summary>
        /// Waits for the thread or any of the wait handles to become signalled
        /// </summary>
        /// <param name="thread">The thread.</param>
        /// <param name="waitHandles">The wait handles.</param>
        /// <returns>0 if the thread was signalled, otherwise 1 + index into the waitHandles array</returns>
        public static int WaitAny(this Thread thread, params WaitHandle[] waitHandles)
        {
            for (; ; )
            {
                if (thread.Join(0))
                    return 0;

                var result = WaitHandle.WaitAny(waitHandles, 100);
                if (result != WaitHandle.WaitTimeout)
                    return result + 1;
            }
        }

        /// <summary>
        /// Waits for any of the threads or any of the wait handles to become signalled
        /// </summary>
        /// <param name="threads">list of threads</param>
        /// <param name="waitHandles">the wait handles</param>
        /// <returns>The index of the thread that was signalled or threads.Length + index into the waitHandles array</returns>
        public static int WaitAny(Thread[] threads, params WaitHandle[] waitHandles)
        {
            for (;;)
            {
                for (var i = 0; i < threads.Length; i++)
                {
                    if (threads[i].Join(0))
                        return i;
                }

                var result = WaitHandle.WaitAny(waitHandles, 100);
                if (result != WaitHandle.WaitTimeout)
                    return result + threads.Length;
            }
        }


    }
}
